feat(auth): per-user provider ownership enforcement#19
Conversation
Extend the openshell.ai/owner label pattern (from sandbox ownership in PR #18) to providers, enabling OIDC-authenticated users to create and manage their own providers on a shared gateway without admin privileges. Changes: - Relax provider CRUD methods from admin to user role in rpc_auth annotations (ImportProviderProfiles/DeleteProviderProfile remain admin) - Stamp owner label on provider create via stamp_owner() - Add ownership checks (check_provider_owner) to get, update, delete, configure-refresh, rotate-credential, and delete-refresh handlers - Filter list_providers to return own + shared for regular users, all for admins - Make ownership.rs docstring entity-generic (shared with sandboxes) - Update authz tests to reflect relaxed role requirements - Add 12 ownership isolation unit tests covering create/get/list/update/ delete with owner, non-owner, admin, and shared provider scenarios Implements kagenti/kagenti#1995 (partial: Tasks 1-2, 5 complete; Tasks 3-4 deferred for follow-up). Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Paolo Dettori <dettori@us.ibm.com>
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Paolo Dettori <dettori@us.ibm.com>
When attaching a provider to a sandbox, verify the provider is either owned by the caller or shared (no owner label). This prevents user A from referencing user B's private provider in their sandbox. Adds two tests: one for the rejection case and one confirming shared providers remain attachable by any user. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Paolo Dettori <dettori@us.ibm.com>
pdettori
left a comment
There was a problem hiding this comment.
Solid, well-tested authz change extending the openshell.ai/owner label pattern from sandboxes (#18) to providers — RBAC relaxed admin→user with enforcement moved into handlers, admin/anonymous backward-compat preserved.
Blocker: CI is red — the Rust clippy gate fails with 10 -D warnings errors (1 in production code at the list filter, 9 in the new test module). Merge is blocked until clippy is clean: cargo clippy --workspace --all-targets -- -D warnings.
Two non-blocking correctness notes inline (per-user list pagination, and the skip-on-not-found ownership guard in update/delete).
Areas reviewed: Rust authz/ownership/provider/sandbox, tests, CI. 3 commits, all signed-off. No .claude/.vscode changes.
Assisted-By: Claude Code
- Fix clippy warnings: unnecessary qualifications, redundant closures, iter_on_single_items, map_or→is_none_or - Fix list pagination for non-admins: loop in batches to guarantee `limit` visible results despite post-fetch filtering - Align update/delete ownership guards to return NOT_FOUND early when the provider doesn't exist, matching get/rotate behavior Signed-off-by: Paolo Dettori <paolo@dettori.dev> Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Paolo Dettori <dettori@us.ibm.com>
Summary
openshell.ai/ownerlabel pattern (from sandbox ownership in feat(auth): per-user sandbox ownership enforcement #18) to providersImplements kagenti/kagenti#1995 (core enforcement; name-scoping and sandbox-binding alignment deferred to follow-up).
Changes
#[rpc_auth]fromrole = "admin"→role = "user"(exceptImportProviderProfiles/DeleteProviderProfile)openshell.ai/ownerlabel on provider createcheck_provider_ownerguard to get, update, delete, configure-refresh, rotate-credential, delete-refreshlist_providersto own + shared for regular users, all for adminsTest plan
Assisted-By: Claude Code